home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / asm4.zip / STATLINE.ASM < prev    next >
Assembly Source File  |  1986-04-17  |  13KB  |  349 lines

  1. ;-----------------------------------------------------------------------;
  2. ; STATLINE, by John Socha, Copyright 1986 Ziff-Davis Publishing Co.    ;
  3. ;                                    ;
  4. ; Here are the two interrupt vectors that we take over.  The first    ;
  5. ; interrupt, INT 9, is the hardware interrupt for the keyboard, and    ;
  6. ; it's called every time you push or release a key.            ;
  7. ;                                    ;
  8. ; The other interrupt, INT 10h, points to the ROM BIOS routines that    ;
  9. ; handle all of the screen I/O.  We intercept it so that we can watch    ;
  10. ; for commands to change the display mode.  Since STATLINE only works    ;
  11. ; in 80x25 text modes, STATLINE turns itself off as long as the screen    ;
  12. ; is in a different mode.                        ;
  13. ;-----------------------------------------------------------------------;
  14. VECTORS        SEGMENT AT 0h
  15.     ORG    9h*4
  16. KEYBOARD_INT_VECTOR    LABEL    DWORD    ;Keyboard interrupt
  17.     ORG    10h*4
  18. VIDEO_IO_VECTOR        LABEL    DWORD    ;ROM BIOS Video I/O function calls
  19. VECTORS        ENDS
  20.  
  21.  
  22. ;-----------------------------------------------------------------------;
  23. ; STATLINE uses the following flags from the ROM BIOS's data area to    ;
  24. ; control the screen.                            ;
  25. ;-----------------------------------------------------------------------;
  26. ROM_BIOS_DATA    SEGMENT AT 40h
  27.     ORG    10h
  28. EQUIP_FLAG    DB    ?        ;Equipment installed
  29.     ORG    17h
  30. KBD_FLAG    DB    ?        ;Used to determine display type
  31.     ORG    4Eh
  32. CRT_START    DW    ?        ;Starting address in buffer
  33.     ORG    63h
  34. ADDR_6845    DW    ?        ;3x8 register, where x is B or D
  35. ROM_BIOS_DATA    ENDS
  36.  
  37.  
  38. ;-----------------------------------------------------------------------;
  39. ; This section of the ROM in a COMPAQ contains the 6 bytes 'COMPAQ'    ;
  40. ; which we can use to identify a COMPAQ computer.  COMPAQ computers    ;
  41. ; have a display adapter that uses the monochrome display, but with    ;
  42. ; registers and memory the same as a color graphics adapter.        ;
  43. ;-----------------------------------------------------------------------;
  44. COMPAQ_CO    EQU    4F43h        ;ASCII code of 'CO'
  45.  
  46. COMPAQ_SEG    SEGMENT AT 0F000h
  47.     ORG    0FFEAh
  48. COMPAQ_ID    DW    ?        ;We should find 'CO' (4F43h) here
  49. COMPAQ_SEG    ENDS
  50.  
  51.  
  52. ;-----------------------------------------------------------------------;
  53. ; Here is the STATLINE's entry point.  It jumps to the initialization    ;
  54. ; routine which is at the very end so that we can throw it out of    ;
  55. ; memory after we've used it.                        ;
  56. ;-----------------------------------------------------------------------;
  57. CODE_SEG    SEGMENT
  58.     ASSUME    CS:CODE_SEG, DS:CODE_SEG
  59.     ORG    100h        ;Reserve for DOS Program Segment Prefix
  60. BEGIN:    JMP    INIT_VECTORS
  61.  
  62. AUTHOR_STRING        DB    "Installed Statline, by John Socha"
  63.             DB    0Dh, 0Ah, '$'
  64.  
  65. OLD_KBD_FLAG        DB    0    ;Most recent upper nibble of status
  66. VIDEO_MODE        DB    ?    ;Current video mode
  67. STATUS_LINE_ENABLED    DB    1    ;0 when we're in graphics modes
  68.  
  69. ;-----------------------------------------------------------------------;
  70. ; The following table contains the character/attribute pairs for the    ;
  71. ; states of the Scroll Lock, Num Lock, and Caps Lock keys.        ;
  72. ;                                    ;
  73. ; The first word contains the address for the character, and the second    ;
  74. ; word contains the character/attribute pair.                ;
  75. ;-----------------------------------------------------------------------;
  76. ENTRY    STRUC
  77. OFFSET_FROM_TOP        DW    ?    ;Offset from start of display memory
  78. ATTRIBUTE_CHARACTER    DB    ?    ;Attribute and character code
  79. ENTRY    ENDS
  80.  
  81. FLAG_CHARACTER_TABLE    LABEL    WORD
  82.     ENTRY    <4084,' '>        ;Scroll Lock, ' '
  83.     ENTRY    <4084,12h>        ;Scroll Lock, double-ended arrow
  84.     ENTRY    <4080,' '>        ;Num Lock, ' '
  85.     ENTRY    <4080,23h>        ;Num lock, '#'
  86.     ENTRY    <4076,' '>        ;Caps Lock, ' '
  87.     ENTRY    <4076,18h>        ;Caps Lock, up arrow
  88.  
  89. ROM_KEYBOARD_INT    DD    ?
  90. ROM_VIDEO_IO_INT    DD    ?
  91.  
  92. ;-----------------------------------------------------------------------;
  93. ; This procedure sends control off to the ROM BIOS routine, then checks    ;
  94. ; the shift-lock flags on return and writes the new flag characters to    ;
  95. ; the screen.                                ;
  96. ;-----------------------------------------------------------------------;
  97. INTERCEPT_KEYBOARD_INT    PROC    FAR
  98.     ASSUME    CS:CODE_SEG, DS:NOTHING
  99.     PUSHF                ;Simulate INT with PUSHF and CALL
  100.     CALL    ROM_KEYBOARD_INT    ;Let ROM do the work
  101.     CMP    STATUS_LINE_ENABLED,1    ;See if Status line enabled.
  102.     JNE    NO_STATUS_LINE        ;Not enabled.
  103.     CALL    CHECK_STATUS_FLAGS    ;Check flags and update status line
  104. NO_STATUS_LINE:
  105.     IRET
  106. INTERCEPT_KEYBOARD_INT    ENDP
  107.  
  108.  
  109. ;-----------------------------------------------------------------------;
  110. ; This procedure checks the current setting of KBD_FLAGS against the    ;
  111. ; last setting, and if the flags have changed, it updates the status    ;
  112. ; line display.  Check_status_flags also updates Old_kbd_flag.        ;
  113. ;-----------------------------------------------------------------------;
  114. CHECK_STATUS_FLAGS    PROC    NEAR
  115.     PUSH    AX            ;Save all the registers we use
  116.     PUSH    BX
  117.     PUSH    CX
  118.     PUSH    DX
  119.     PUSH    SI
  120.     PUSH    DI
  121.     PUSH    DS
  122.     PUSH    ES
  123.     ASSUME    CS:CODE_SEG, DS:ROM_BIOS_DATA
  124.     MOV    AX,ROM_BIOS_DATA    ;Set DS so it points to BIOS data area
  125.     MOV    DS,AX
  126.     MOV    DX,ADDR_6845        ;Get the base address for the 6845
  127.     MOV    AX,0B800h        ;Segment address of graphics adapter
  128.     CMP    DX,3D0h            ;Is this the color graphics adapter?
  129.     JAE    IS_COLOR_BOARD      ;It's a color board, so don't change AX
  130.     MOV    AX,0B000h           ;Segment address for monochrome adapter
  131. IS_COLOR_BOARD:
  132.     MOV    ES,AX            ;Use extra segment for display memory
  133.  
  134.     ADD    DX,03DAh-03D4h        ;Point to status register
  135.     MOV    BL,KBD_FLAG        ;Get flag information
  136.     MOV    CL,4                ;Put shift lock flags into lower nibble
  137.     SHR    BL,CL
  138.     ASSUME    CS:CODE_SEG, DS:CODE_SEG
  139.     MOV    AX,CS            ;Set DS to the local data (in CS)
  140.     MOV    DS,AX
  141.     CMP    BL,OLD_KBD_FLAG        ;Have any of the status flags changed?
  142.     JE    FLAGS_HAVENT_CHANGED    ;No, then do nothing
  143.     MOV    OLD_KBD_FLAG,BL        ;Flags have changed, update status line
  144.     MOV    SI,Offset FLAG_CHARACTER_TABLE
  145.  
  146.     MOV    CX,3            ;Repeat for three shift lock keys
  147. SHIFT_LOCK_LOOP:
  148.     PUSH    SI
  149.     SHR    BL,1            ;Get next flag in carry
  150.     JNC    READ_OFFSET        ;Flag was 0, SI Ok
  151.     ADD    SI,3            ;Skip over information
  152. READ_OFFSET:
  153.     MOV    DI,[SI]            ;Get Offset
  154.     MOV    AL,[SI+2]        ;Get character for this flag
  155.     
  156.     PUSH    CX            ;Save the CX register
  157.     MOV    CL,AL            ;Save the character in CL
  158. WAIT_FOR_NON_RETRACE:
  159.     IN    AL,DX            ;Read status
  160.     TEST    AL,8            ;In vertical retrace?
  161.     JNZ    WAIT_FOR_NON_RETRACE    ;Wait for vertical retrace to finish
  162. WAIT_FOR_RETRACE:
  163.     IN    AL,DX            ;Read status
  164.     TEST    AL,8            ;In vertical retrace?
  165.     JZ    WAIT_FOR_RETRACE    ;No, then wait for vertical retrace
  166.     MOV    AL,CL            ;Get the character we want to write
  167.     STOSB                ;Write character to the screen
  168.     POP    CX            ;Recover the old value of CX
  169.  
  170.     POP    SI
  171.     ADD    SI,6            ;Skip to next pair of entries
  172.     LOOP    SHIFT_LOCK_LOOP
  173.  
  174. FLAGS_HAVENT_CHANGED:
  175.     POP    ES
  176.     POP    DS
  177.     POP    DI
  178.     POP    SI
  179.     POP    DX
  180.     POP    CX
  181.     POP    BX
  182.     POP    AX
  183.     RET
  184. CHECK_STATUS_FLAGS    ENDP
  185.  
  186.  
  187. ;-----------------------------------------------------------------------;
  188. ; This procedure reprograms the 6845 whenever a program switches modes    ;
  189. ; into an 80x25 text mode.                        ;
  190. ;-----------------------------------------------------------------------;
  191. INTERCEPT_VIDEO_IO    PROC    FAR
  192.     ASSUME    CS:CODE_SEG, DS:NOTHING
  193.     OR    AH,AH            ;Check if called for SET MODE
  194.     JZ    SET_MODE        ;It's a SET MODE call
  195.     JMP    ROM_VIDEO_IO_INT    ;Not a SET MODE, call ROM BIOS
  196. SET_MODE:
  197.     MOV    VIDEO_MODE,AL        ;Save new video mode
  198.     MOV    STATUS_LINE_ENABLED,AH    ;Disable STATLINE during mode change
  199.     PUSHF                ;Simulate INT with PUSHF, CALL
  200.     CALL    ROM_VIDEO_IO_INT    ;Let ROM BIOS change video mode
  201.     CALL    REPROGRAM_6845        ;Create 26th line again
  202.     MOV    OLD_KBD_FLAG,0        ;Flags will be clear in new mode
  203.     CALL    CHECK_STATUS_FLAGS    ;Make sure we show current flags
  204.     IRET
  205. INTERCEPT_VIDEO_IO    ENDP
  206.  
  207.  
  208.  
  209. ;-----------------------------------------------------------------------;
  210. ; The following tables describe how to reprogram the 6845 registers.    ;
  211. ; Each pair describes how to change one register.  The first number is    ;
  212. ; the register that we want to reprogram, while the second number is    ;
  213. ; the new value for that register.  Reprogram_6845 stops when it sees    ;
  214. ; a 0 for the register number.                        ;
  215. ;-----------------------------------------------------------------------;
  216. MONOCHROME_TABLE    LABEL    BYTE
  217.     DB    4,26            ;Vertical total, 26 lines
  218.     DB    5,3            ;Vertical total adjust, scan lines
  219.     DB    6,26            ;Vertical displayed, 26 lines
  220.     DB    7,26            ;Vertical sync position, lines
  221.     DB    0            ;End of Monochrome table
  222.     
  223. COLOR_GRAPHICS_TABLE:
  224.     DB    6,26            ;Vertical displayed
  225.     DB    0            ;End of color graphics adapter table
  226.  
  227. ;-----------------------------------------------------------------------;
  228. ; This procedure reprograms the 6845 so that it will show 26 rather    ;
  229. ; than 25 lines.  It uses the values from one of the tables above.    ;
  230. ;                                    ;
  231. ; This procedure also handles the COMPAQ, which is a special case.  The    ;
  232. ; COMPAQ uses a monochrome-type display, so it needs to be reprogrammed    ;
  233. ; like a monochrome display, yet writes should be to 3Dxh registers    ;
  234. ; rather than the 3Bxh registers used for an IBM monochrome display.    ;
  235. ;                                    ;
  236. ; F000:FFEA holds the word 'COMPAQ' on COMPAQ computers, so we can tell    ;
  237. ; when we're running on a COMPAQ.                    ;
  238. ;-----------------------------------------------------------------------;
  239. REPROGRAM_6845    PROC    NEAR
  240.     ASSUME    CS:CODE_SEG, DS:CODE_SEG
  241.     PUSH    AX
  242.     PUSH    CX
  243.     PUSH    DX
  244.     PUSH    SI
  245.     PUSH    DS
  246.     MOV    AX,CS
  247.     MOV    DS,AX            ;Set up Data Seg
  248.     MOV    STATUS_LINE_ENABLED,0    ;Initially disable status line
  249.     MOV    AL,VIDEO_MODE        ;Check video mode
  250.     CMP    AL,1            ;In graphics mode?
  251.     JLE    GRAPHICS_MODE        ;Yes, don't reprogram 6845
  252.     CMP    AL,3            ;Is display in a text mode?
  253.     JLE    TEXT_MODE        ;Yes, then we can reprogram 6845
  254.     CMP    AL,7            ;Is it in the monochrome mode?
  255.     JNE    GRAPHICS_MODE        ;No, then don't reprogram 6845
  256. TEXT_MODE:                ;Yes, reprogram 6845
  257.     MOV    STATUS_LINE_ENABLED,1    ;Enable status line in text modes
  258.     MOV    SI,Offset MONOCHROME_TABLE
  259.     MOV    DX,3B4h            ;6845 registers for monochrome display
  260.     PUSH    DS
  261.     MOV    AX,ROM_BIOS_DATA    ;Read equipment flag from low memory
  262.     MOV    DS,AX
  263.     ASSUME    CS:CODE_SEG, DS:ROM_BIOS_DATA
  264.     MOV    AL,EQUIP_FLAG
  265.     AND    AL,30h            ;Isolate CRT switches
  266.     CMP    AL,30h            ;Is it the monochrome display?
  267.     POP    DS
  268.     JE    SET_REGISTERS        ;Yes, the registers are correct
  269.     MOV    DX,3D4h            ;No, set registers for graphics adapter
  270.     PUSH    DS
  271.     MOV    AX,COMPAQ_SEG        ;Now check to see if this is a COMPAQ
  272.     MOV    DS,AX
  273.     ASSUME    CS:CODE_SEG, DS:COMPAQ_SEG
  274.     CMP    COMPAQ_ID, COMPAQ_CO    ;Is this the 'CO' from COMPAQ?
  275.     POP    DS            ;Restore old DS
  276.     ASSUME    CS:CODE_SEG, DS:CODE_SEG
  277.     JE    SET_REGISTERS        ;Is a COMPAQ, use monochrome data
  278.     MOV    SI,Offset COLOR_GRAPHICS_TABLE    ;No, use color graphics data
  279.  
  280. SET_REGISTERS:
  281.     CLD                ;Clear direction flag for increment
  282. ADAPTER_LOOP:
  283.     LODSB                ;Get register number
  284.     OR    AL,AL            ;Are we at the end of the table?
  285.     JZ    END_OF_ADAPTER_TABLE    ;Yes, we're almost done
  286.     OUT    DX,AL            ;No, select this register
  287.     INC    DX            ;Point to data register
  288.     LODSB                ;Get new register value
  289.     OUT    DX,AL            ;Set the register to its new value
  290.     DEC    DX            ;Point back to address register
  291.     JMP    ADAPTER_LOOP        ;Get the next register/value pair
  292.  
  293. END_OF_ADAPTER_TABLE:
  294. GRAPHICS_MODE:
  295.     POP    DS
  296.     POP    SI
  297.     POP    DX
  298.     POP    CX
  299.     POP    AX
  300.     RET
  301. REPROGRAM_6845    ENDP
  302.  
  303.  
  304. ;-----------------------------------------------------------------------;
  305. ; This procedure initializes the interrupt vectors and the 6845        ;
  306. ; registers.  It initializes both the Monochrome and color graphics    ;
  307. ; adapter address so it will work on the COMPAQ as well as IBM PCs    ;
  308. ;-----------------------------------------------------------------------;
  309. INIT_VECTORS    PROC    NEAR
  310.     ASSUME    CS:CODE_SEG, DS:CODE_SEG
  311.     LEA    DX,AUTHOR_STRING    ;Print out the author notice
  312.     MOV    AH,9            ;Display this string
  313.     INT    21h
  314.  
  315.     MOV    AH,15            ;Check current video mode
  316.     INT    10h            ;Call VIDEO_IO ROM BIOS routine
  317.     MOV    VIDEO_MODE,AL
  318.     CALL    REPROGRAM_6845
  319.     CALL    CHECK_STATUS_FLAGS    ;Display any flags now on
  320.  
  321.     ASSUME    CS:CODE_SEG, DS:VECTORS
  322.     MOV    AX,VECTORS        ;Set up the data segment for vectors
  323.     MOV    DS,AX
  324.     CLI                ;Don't allow interrupts
  325.  
  326.     MOV    AX,Word Ptr KEYBOARD_INT_VECTOR
  327.     MOV    Word Ptr ROM_KEYBOARD_INT,AX
  328.     MOV    AX,Word Ptr KEYBOARD_INT_VECTOR[2]
  329.     MOV    Word Ptr ROM_KEYBOARD_INT[2],AX
  330.     MOV    Word Ptr KEYBOARD_INT_VECTOR, Offset INTERCEPT_KEYBOARD_INT
  331.     MOV    Word Ptr KEYBOARD_INT_VECTOR[2],CS
  332.  
  333.     MOV    AX,Word Ptr VIDEO_IO_VECTOR
  334.     MOV    Word Ptr ROM_VIDEO_IO_INT,AX
  335.     MOV    AX,Word Ptr VIDEO_IO_VECTOR[2]
  336.     MOV    Word Ptr ROM_VIDEO_IO_INT[2],AX
  337.     MOV    Word Ptr VIDEO_IO_VECTOR, Offset INTERCEPT_VIDEO_IO
  338.     MOV    Word Ptr VIDEO_IO_VECTOR[2],CS
  339.     
  340.     STI                ;Allow interrupts again
  341.     MOV    DX,Offset INIT_VECTORS    ;End of resident portion
  342.     INT    27h            ;Terminate but stay resident
  343. INIT_VECTORS    ENDP
  344.  
  345.  
  346. CODE_SEG    ENDS
  347.  
  348.     END    BEGIN
  349.